package evtop

import (
	"github.com/pkg/errors"
	"gogs.xiaoyuanjijiehao.com/antlinker/antcms/core/columnd"
	"gogs.xiaoyuanjijiehao.com/antlinker/antcms/core/groupd"
	"gogs.xiaoyuanjijiehao.com/antlinker/antcms/core/infod"
	"gogs.xiaoyuanjijiehao.com/antlinker/antcms/core/interactiond"
	"gogs.xiaoyuanjijiehao.com/antlinker/antcms/ddd"
	"gogs.xiaoyuanjijiehao.com/antlinker/antcms/log"
)

type infoListener struct {
	base

	iar  infod.InfoAggregateRoot
	car  columnd.ColumnAggregateRoot
	gar  groupd.GroupAggregateRoot
	igar interactiond.GroupAggregateRoot
}

func (l infoListener) getInfoAndColumn(ctx ddd.Context, infoid string) (info *infod.InfoAggregate, col *columnd.ColumnAggregate, err error) {
	info, err = l.iar.GetInfo(ctx, infoid)
	if err != nil {
		log.Warn("onInfoAdd 获取信息失败：%+v", err)
		return
	}
	col, err = l.car.GetColumn(ctx, info.ColumnID)
	if err != nil {
		log.Warn("onInfoAdd 获取信息所在栏目失败：%+v", err)
		return
	}
	return
}
func (l infoListener) onInfoAdd() ddd.EventListener {
	return l.creEventListener(func(ctx ddd.Context, evt ddd.Event) error {
		log.Debugf("执行事件监听: onInfoAdd :%#v", evt)
		id, ok := evt.Data.(string)
		if !ok {
			return errors.Errorf("获取事件数据格式错误：%#v", evt.Data)
		}
		info, col, err := l.getInfoAndColumn(ctx, id)
		if err != nil {
			return errors.Wrapf(err, "获取信息失败：%v", err)
		}

		if col.Kind != columnd.ColumnKindInteractive {
			// 不是互动平台

		}
		if info.Status == infod.IStatusPublished {
			if err := col.UpdatePubInfoNum2(ctx, 1); err != nil {
				return errors.Wrapf(err, "更新失败：%v", err)
			}
			// 触发组内信息的添加

		} else {
			if err := col.UpdateInfoNum(ctx, 1); err != nil {
				return errors.Wrapf(err, "更新失败：%v", err)
			}
		}
		return nil
	})

}

func (l infoListener) onInfoPublish() ddd.EventListener {
	return l.creEventListener(func(ctx ddd.Context, evt ddd.Event) error {
		log.Debugf("执行事件监听: onInfoPublish :%#v", evt)
		eadata, ok := evt.Data.(*infod.EvtActData)
		if !ok {
			return errors.Errorf("获取事件数据格式错误：%#v", evt.Data)

		}
		col, err := l.car.GetColumn(ctx, eadata.New.ColumnID)
		if err != nil {
			return errors.Wrapf(err, "获取信息所在栏目失败：%+v", err)
		}
		//log.Debugf("%#v", col)
		//log.Debugf("%#v", col.Kind)
		//if col.Kind != columnd.ColumnKindInteractive {
		// 不是互动平台
		return col.UpdatePubInfoNum(ctx, 1)
		//}
		// 触发组内信息的添加
		//return nil
	})
}

func (l infoListener) onInfoUnpublish() ddd.EventListener {
	return l.creEventListener(func(ctx ddd.Context, evt ddd.Event) error {

		log.Debugf("执行事件监听: onInfoUnpublish :%#v", evt)
		eadata, ok := evt.Data.(*infod.EvtActData)
		if !ok {
			return errors.Errorf("获取事件数据格式错误：%v", evt.Data)
		}
		col, err := l.car.GetColumn(ctx, eadata.New.ColumnID)
		if err != nil {
			return errors.Wrapf(err, "获取信息所在栏目失败：%+v", err)

		}

		if col.Kind != columnd.ColumnKindInteractive {
			// 不是互动平台
			return col.UpdatePubInfoNum(ctx, -1)
		}
		// 触发组内信息的删除
		return nil
	})
}

// onInfoDescChg 信息发生修改时监听信息发生变化，修改相应的栏目统计信息
func (l infoListener) onInfoDescChg() ddd.EventListener {
	return l.creEventListener(func(ctx ddd.Context, evt ddd.Event) error {
		log.Debugf("执行事件监听: onInfoDescChg :%#v", evt)
		// 取出原来的信息
		// 取出新的修改信息描述
		// 如果栏目没有修改返回
		// 如果栏目修改了
		// 原来信息状态已发布 ，调整两个栏目的信息数量和发布信息数量 原栏目-1 新栏目+1
		// 原来信息状态不是删除和发布，则修改两个栏目的信息数量 原栏目-1 新栏目+1
		if evt.Data == nil {
			return nil
		}
		if data, ok := evt.Data.(*infod.EvtUpdateDescData); ok {
			if data.Old.ColumnID == data.NewDesc.ColumnID {
				return nil
			}
			if data.Old.Status == infod.IStatusDeleted {
				return nil
			}
			if data.Old.Status == infod.IStatusPublished {
				// 调整发布信息数量
				// 调整信息数量
				return nil
			}
			if data.Old.Status > infod.IStatusDeleted && data.Old.Status < infod.IStatusPublished {

				// 调整信息数量
				oldcol, err := l.car.GetColumn(ctx, data.Old.ColumnID)
				if err != nil {
					return errors.Wrapf(err, "onInfoDescChg 获取信息所在栏目失败：%v", err)
				}
				err = oldcol.UpdateInfoNum(ctx, -1)
				if err != nil {
					log.Warn("onInfoDescChg 更新原栏目的信息数量失败：%+v", err)
				}

				// 调整信息数量
				newcol, err := l.car.GetColumn(ctx, data.NewDesc.ColumnID)
				if err != nil {
					return errors.Wrapf(err, "获取信息所在栏目失败：%v", err)

				}
				err = newcol.UpdateInfoNum(ctx, 1)
				if err != nil {
					return errors.Wrapf(err, "更新新栏目的信息数量失败：%v", err)
				}
			}
		}
		return nil
	})
}

// onInfoDelete 信息删除时，修改相应的栏目统计信息
func (l infoListener) onInfoDelete() ddd.EventListener {
	return l.creEventListener(func(ctx ddd.Context, evt ddd.Event) error {

		log.Debugf("执行事件监听: onInfoDelete :%#v", evt)
		eadata, ok := evt.Data.(*infod.EvtActData)
		if !ok {
			return errors.Errorf("获取事件数据格式错误：%#v", evt.Data)
		}
		col, err := l.car.GetColumn(ctx, eadata.New.ColumnID)
		if err != nil {
			return errors.Wrapf(err, "获取信息所在栏目失败：%v", err)
		}

		if col.Kind != columnd.ColumnKindInteractive && eadata.Old.Status != infod.IStatusDeleted {
			// 不是互动平台 并且删除前不是已删除信息
			if eadata.Old.Status == infod.IStatusPublished {
				return col.UpdatePubInfoNum2(ctx, -1)
			}
			return col.UpdateInfoNum(ctx, -1)
		}
		// 触发组内信息的添加
		return nil
	})
}

// onInfoDelete 信息删除时，修改相应的栏目统计信息
// 删除信息所在栏目为columnd.InfoModeSingle模式时,删除文章自动销毁
func (l infoListener) onInfoDeleteAutoDestroy() ddd.EventListener {
	return l.creEventListener(func(ctx ddd.Context, evt ddd.Event) error {

		log.Debugf("执行事件监听: onInfoDeleteAutoDestroy :%#v", evt)
		eadata, ok := evt.Data.(*infod.EvtActData)
		if !ok {
			return errors.Errorf("获取事件数据格式错误：%#v", evt.Data)
		}
		col, err := l.car.GetColumn(ctx, eadata.New.ColumnID)
		if err != nil {
			return errors.Wrapf(err, "获取信息所在栏目失败：%v", err)
		}
		if col.InfoMode == columnd.InfoModeSingle {
			// 删除后自动销毁
			i, err := l.iar.GetInfo(ctx, eadata.New.InfoID)
			if err != nil {
				return err
			}
			i.Destroy(ctx)

		}

		return nil
	})
}
